/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.volatileshooter.entity.player;

import org.newdawn.slick.Input;
import org.newdawn.slick.geom.Vector2f;

import com.volatileshooter.entity.Bucket;
import com.volatileshooter.entity.Entity;
import com.volatileshooter.entity.EntityController;
import com.volatileshooter.entity.EntityEvent;
import com.volatileshooter.entity.EntityManager;
import com.volatileshooter.entity.blackhole.BlackHoleEntity;
import com.volatileshooter.entity.bullets.BulletEntity;
import com.volatileshooter.state.input.KeyboardEvent;
import com.volatileshooter.state.input.MouseEvent;

/**
 * 
 * @author Ahmed
 */
public class PlayerController implements EntityController {
	private final float MOVEMENT_SPEED = 1.1f;
	private final float MASS = 1f;

	private Vector2f pos;
	private Vector2f vel;
	private Vector2f accel;
	private Vector2f force;

	private Vector2f oldPos;
	private Vector2f oldVel;
	
	private float lastBullet;

	public PlayerController(PlayerEntity entity) {
		pos = new Vector2f(entity.getPosition());
		accel = new Vector2f();
		vel = new Vector2f();
		force = new Vector2f();

		oldVel = new Vector2f();
		oldPos = new Vector2f(pos);
	}

	@Override
	public void update(float time, Entity parent) {
		lastBullet += time;
		accumulateForces();
		force.set(0, 0);
		vel.x = (accel.x * time) + oldVel.x;
		vel.y = (accel.y * time) + oldVel.y;
		oldVel.set(vel);

		pos.x = (vel.x * time) + oldPos.x;
		pos.y = (vel.y * time) + oldPos.y;
		oldPos.set(pos);
		((PlayerEntity) parent).getPosition().set(pos);
	}

	@Override
	public void event(EntityEvent event) {
		if (event instanceof KeyboardEvent) {
			KeyboardEvent keys = (KeyboardEvent) event;
			handleMovement(keys);
		}

		if (event instanceof MouseEvent) {
			// calculate direction
			MouseEvent mouse = (MouseEvent) event;
			if (mouse.getMouseButtonDown() == 0 && lastBullet >= 0.5f) {
				lastBullet = 0f;
				float dirx = mouse.getX() - pos.x;
				float diry = mouse.getY() - pos.y;
				EntityManager.instance().getBucket("bullets").getEntities()
						.add(
								new BulletEntity(new Vector2f(pos),
										new Vector2f(dirx, diry)));
			}
		}
	}

	private void accumulateForces() {
		// black holes
		Vector2f scratch = new Vector2f();
		Bucket holesBucket = EntityManager.instance().getBucket("blackholes");
		for (int i = holesBucket.getEntities().size(); --i >= 0;) {
			BlackHoleEntity entity = (BlackHoleEntity) holesBucket
					.getEntities().get(i);
			scratch.set(entity.getPosition());
			scratch.sub(pos);

			float strength = scratch.length();
			scratch.normalise();
			scratch.scale(((entity.getStrength() * MASS) / strength) + 1);

			force.add(scratch);
		}
		accel.x = force.x / MASS;
		accel.y = force.y / MASS;
	}

	private void handleMovement(KeyboardEvent keys) {
		if (keys.isKeyDown(Input.KEY_W)) {
			force.y -= MOVEMENT_SPEED;
		} else if (keys.isKeyDown(Input.KEY_S)) {
			force.y += MOVEMENT_SPEED;
		}

		if (keys.isKeyDown(Input.KEY_A)) {
			force.x -= MOVEMENT_SPEED;
		} else if (keys.isKeyDown(Input.KEY_D)) {
			force.x += MOVEMENT_SPEED;
		}
	}
}
